grammar Sample3;

options {
  language = Java;
}


@header {
  package sample3.gen;
  import sample3.evaluators.*;
}
@lexer::header {

  package sample3.gen;
}

evaluator returns [Evaluator e]
  : expression EOF {$e = $expression.e;}
  ;

term returns [Evaluator e]
  :IDENT {$e = new IntEvaluator(0);}  
  |'('expression')' {$e = $expression.e;}
  |INTEGER{$e = new IntEvaluator(Integer.parseInt($INTEGER.text));}
  ;

unary returns [Evaluator e]
  :{boolean positive = true;}
    ('+'|'-'{positive = !positive;})* term
    { 
      $e = $term.e;
      if(!positive)
        $e = new NegationEvaluator($e);
    }
  ;
  
 mult returns [Evaluator e]
  :op1=unary {$e = $op1.e;}
  (
  '*'     op2=unary{$e = new TimesEvaluator($e, $op2.e);}
  |'/'    op2=unary{$e = new DivEvaluator($e, $op2.e);}
  |'mod'  op2=unary{$e = new ModEvaluator($e, $op2.e);}
  )*
  ;
 
expression returns [Evaluator e]
  :op1=mult {$e = $op1.e;}
  ('+' op2=mult{$e = new PlusEvaluator($e, $op2.e);}
  |'-' op2=mult{$e = new MinusEvaluator($e, $op2.e);}
  )*
  ;

INTEGER : '0'..'9'+;
IDENT : ('a'..'z' | 'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'9' )*; 
WS: (' '|'\t'|'\n'|'\r'|'\f')+ {$channel = HIDDEN;};

rule: ;
